﻿// MakingWaves: GeoProperties

/*global document window EPi google alert $ */

function GeoPicker(controlsId, options) {
    var self = this;
    this.controlsId = controlsId;
    this.options = options;

    this.map = null;
    this.geocoder = null;
    this.marker = null;
    this.infoWindow = null;

    this.initializeMap = function () {

        var mapOptions = { center: new google.maps.LatLng(0, 0), zoom: 0, mapTypeId: google.maps.MapTypeId.ROADMAP },
            markerPos = new google.maps.LatLng(0, 0);

        if (this.options.geoPoint) {
            var geoPoint = JSON.parse(this.options.geoPoint);
            markerPos = new google.maps.LatLng(geoPoint.latitude, geoPoint.longitude);
            mapOptions.center = markerPos;
            mapOptions.zoom = parseInt(geoPoint.mapZoom, 10);
        }

        this.infoWindow = new google.maps.InfoWindow();
        this.map = new google.maps.Map(document.getElementById(this.controlsId.mapContainerId), mapOptions);
        this.addMarker(markerPos);

        this.geocoder = new google.maps.Geocoder();

        this.initializeLocation(markerPos);

        google.maps.event.addListener(this.map, "click", this.getAddressFromClick);
        var inputZoomControl = document.getElementById(self.controlsId.zoomTextBoxId);
        if (!inputZoomControl) return;
        inputZoomControl.value = this.map.getZoom();
        google.maps.event.addListener(this.map, 'zoom_changed', function () {
            document.getElementById(self.controlsId.zoomTextBoxId).value = this.getZoom();
        });
    };

    this.initializeLocation = function(markerPos) {
        if (markerPos.lat() != 0 && markerPos.lng() != 0) {
            this.getAddress(markerPos);
        }
        this.showLocation(markerPos);
    };

    this.searchAddress = function (event) {
        event.preventDefault();
        var address = $("#" + self.controlsId.searchTextBoxId).val();
        if (self.geocoder) {
            self.geocoder.geocode({ 'address': address }, function (results, status) {
                if (status === google.maps.GeocoderStatus.OK) {

                    self.map.setCenter(results[0].geometry.location);
                    var point = results[0].geometry.location;

                    self.selectMarkerLocation(point);

                    self.setInfoWindow(address);
                    self.updateLocationField(address);

                    self.showLocation(point);

                    self.map.setZoom(11);

                } else {
                    alert(address + " not found");
                }
            });
        }
    };    

    this.selectMarkerLocation = function(point) {
        if (!self.marker) {
            self.addMarker(point);
        } else {
            self.marker.setPosition(point);
        }
    };

    this.gotoLocation = function (point) {
        if ((!point.lat()) || (!point.lng())) {            
            return;
        }
        this.selectMarkerLocation(point);
        this.getAddress(point);
    };

    this.addMarker = function (point) {
        this.marker = new google.maps.Marker({ map: this.map, position: point, draggable: true });        
        this.marker.setMap(this.map);
        google.maps.event.addListener(this.marker, "dragend", this.markerDragged);
    };

    this.markerDragged = function () {
        var newPoint = self.marker.getPosition();
        self.getAddress(newPoint);
        self.showLocation(newPoint);
    };

    this.getAddressFromClick = function (mouseEventArg) {
        self.getAddress(mouseEventArg.latLng);
        self.showLocation(mouseEventArg.latLng);
    };

    this.getAddress = function (latlng) {
        if (latlng !== null) {
            
            var msg = this.marker.getPosition().toString();
            this.infoWindow.close();
            this.updateLocationField(msg);

            this.geocoder.geocode({ 'latLng': latlng }, this.showAddress);
        }
    };

    this.setInfoWindow = function (content) {
        this.infoWindow.setContent(content);
        this.infoWindow.open(this.map, this.marker);
    };       

    this.showAddress = function (response, status) {
        var address = "",
            place,
            pointLatLng,
            msg = "";

        if (status === google.maps.GeocoderStatus.OK) {
            place = response[0];
            address = place.formatted_address;
            pointLatLng = place.geometry.location;
            if (!self.marker) {
                self.addMarker(pointLatLng);
            } else {
                self.marker.setPosition(pointLatLng);
            }
        }

        if (address !== "") {
            msg = address;
        } else if (self.marker) {
            msg = self.marker.getPosition().toString();
        }

        self.setInfoWindow(msg);
        self.updateLocationField(msg);

        document.getElementById(self.controlsId.searchTextBoxId).value = msg;
        $("#" + self.controlsId.searchTextBoxId).focus();
    };

    this.showLocation = function(pointLatLng) {
        document.getElementById(self.controlsId.latTextBoxId).value = pointLatLng.lat();
        document.getElementById(self.controlsId.lngTextBoxId).value = pointLatLng.lng();
    };

    this.updateLocationField = function (locationName) {
        if (!this.marker) {
            return;
        }
        this.options.latitude = this.marker.getPosition().lat();
        this.options.longitude = this.marker.getPosition().lng();
        this.options.address = locationName;
    };

    this.onOK = function (event) {
        event.preventDefault();
        EPi.GetDialog().Close({ PageLeaveCheck: true,
            Marker: { Lat: self.options.latitude,
                Lng: self.options.longitude,
                Address: self.options.address,
                Zoom: self.map.getZoom()
            }
        });
    };

    this.onCancel = function (event) {
        event.preventDefault();
        EPi.GetDialog().Close({ PageLeaveCheck: false });
    };
    this.initialize = function () {
        $("#" + controlsId.searchButtonId).click(this.searchAddress);
        this.initializeMap();
        $("#" + controlsId.searchTextBoxId).keydown(function (e) {
            if (e.keyCode === 13) {
                e.preventDefault();
                $("#" + controlsId.searchButtonId).click();
            }
        });
        $("#" + controlsId.searchTextBoxId)[0].focus();
    };
    this.initialize();
}